import axios from 'axios'
import nprogress from 'nprogress'
import 'nprogress/nprogress.css'
import { checkStatus } from './config/checkStatus'
import { ElMessage } from 'element-ui'
import { HttpEnum } from '@/enums/index'
import { local } from '@/utils/storage'
import { LOGIN_URL } from '@/config/config'
import { AxiosCanceler } from './helper/axiosCancel'
import router from '@/routers'
const service = axios.create({
  //配置对象
  //基础路径，发送请求的时候，路径当中会出现api
  baseURL: process.env.VUE_APP_API_BASE_URL,
  // baseURL: '/test',
  //代表请求超时的时间5s
  timeout: HttpEnum.TIMEOUT
  // method: 'post'
})
const axiosCanceler = new AxiosCanceler()
//请求拦截器，在发送之前，请求拦截器可以检测到，可以在请求发出去之前做一些事情
service.interceptors.request.use(config => {
  nprogress.start()
  if (config.cancel === undefined || config.cancel === null) {
    config.cancel = true
  }
  config.cancel && axiosCanceler.addPending(config)
  const token = ''
  config.headers.Authorization = `Bearer ${token}`
  return config
})
service.interceptors.response.use(
  res => {
    nprogress.done()
    const { data } = res
    // * 登陆失效（code == 401）
    if (data.code == HttpEnum.OVERDUE) {
      ElMessage.error(data.msg)
      local.clear()
      router.replace(LOGIN_URL)
      return data
    }

    return data
  },
  error => {
    nprogress.done()
    const { response } = error
    // 请求超时 && 网络错误单独判断，没有 response
    if (error.message.indexOf('timeout') !== -1) ElMessage.error('请求超时！请您稍后重试')
    if (error.message.indexOf('Network Error') !== -1) ElMessage.error('网络错误！请您稍后重试')
    // 根据响应的错误状态码，做不同的处理
    if (response) checkStatus(response.status)
    // 服务器结果都没有返回(可能服务器错误可能客户端断网)，断网处理:可以跳转到断网页面
    if (!window.navigator.onLine) router.replace('/500')
    return Promise.reject(error)
  }
)

const https = {
  // * 常用请求方法封装
  get: (url, pamare = {}, _object = {}) => {
    return service({
      url,
      method: 'get',
      pamare,
      ..._object
    })
  },
  post: (url, data = {}, _object = {}) => {
    return service({
      url,
      method: 'post',
      data,
      ..._object
    })
  },
  delete: (url, pamare = {}, _object = {}) => {
    return service({
      url,
      method: 'delete',
      pamare,
      ..._object
    })
  },
  put: (url, data = {}, _object = {}) => {
    return service({
      url,
      method: 'put',
      data,
      ..._object
    })
  },
  download(url, params = {}, _object = {}) {
    return this.service.post(url, params, { ..._object, responseType: 'blob' })
  },
  original: () => {
    return service
  }
}

export default https
